#!/usr/bin/env python3.9
# You'll need to change a few obvious things.
# Amateur Radio and Amateur Programmer!
# Chris Baird <cjb@brushtail.apana.org.au> did this January 2022

import sys
from PIL import Image, ImageDraw, ImageFont

imagesize = (320,256)
colourspace = "YCbCr" # the content has the greyscale channel all to itself
yskip = 4
ditlen = 2 # size of dits in pixels
(margintop, marginleft, marginright, marginbot) = (8,12,imagesize[0]-12,imagesize[1]-8)
y = margintop
charcount = 0
charsize = imagesize[0] // 8
fnt = ImageFont.truetype("/usr/home/cjb/.fonts/microgramma.ttf", charsize)
morsetable = \
( 128, 174,  74, 128,  19, 128,  68, 122, 180, 182, 128,  84,
  206, 134,  86, 148, 252, 124,  60,  28,  12,   4, 132, 196,
  228, 244, 226, 170, 128, 140, 128,  50, 106,  96, 136, 168,
  144,  64,  40, 208,   8,  32, 120, 176,  72, 224, 160, 240,
  104, 216,  80,  16, 192,  48,  24, 112, 104, 184, 200)

def morse2string (c):
    global charcount
    s = ""
    c = ord(c) - 32
    if c > 64 and c < 91: c -= 32
    if c >= 0 and c < 59:
        charcount += 1
        b = morsetable[c]
        if b == 128: s += " "*2
        while (b & 255) != 128:
            if (b & 128): s += "... "
            else: s += ". "
            b <<= 1
        s += " "*2
    return s


def drawditline (cwstring):
    global y
    x = (imagesize[0] - ditlen*len(cwstring)) // 2

    for i in range(len(cwstring)):
        if cwstring[i] == '.': c = 0
        else: c = 255
        for j in range(ditlen):
            p = im.getpixel ((x,y))
            im.putpixel ((x,y), (c, p[1], p[2]))
            x += 1
    y += yskip


im = Image.new(mode=colourspace, size=imagesize, color=(255,128,128))
d = ImageDraw.Draw (im)
d.text((charsize*1.25,charsize*0.5), "VK2CJB", font=fnt, fill=(128,255,255))
d.text((charsize*1.5,charsize*2), "MORSE", font=fnt, fill=(128,128,255))
d.text((charsize*0.75,charsize*3), "CONTENT", font=fnt, fill=(128,255,128))


ss=""
while y < marginbot:
    c = sys.stdin.read(1)
    if c == '': break
    s = morse2string (c)
    if len(s)+len(ss) >= (marginright-marginleft)//ditlen:
        drawditline(ss)
        ss = ""
    ss += s
drawditline(ss)

imrgb = im.convert("RGB")
imrgb.save("morseencoded.png")
print ("Character count =", charcount)
